See
http://www.openwall.com/lists/oss-security/2016/09/27/4
https://bugs.gentoo.org/show_bug.cgi?id=595542

diff -r 598821da69f2 -r 34fb3aa5e6b4 openslp/common/slp_compare.c
--- a/common/slp_compare.c	Sat Jun 08 15:14:45 2013 -0600
+++ b/common/slp_compare.c	Mon Nov 30 20:50:12 2015 -0700
@@ -194,7 +194,8 @@
  * @return The new (shorter) length of @p str.
  *
  * @note This routine assumes that leading and trailing white space have
- *    already been removed from @p str.
+ *    already been removed from @p str. It also assumes that @p str may
+ *    not be null-terminated.
  */
 static int SLPFoldWhiteSpace(size_t len, char * str)
 {
@@ -203,11 +204,11 @@
    {
       if (isspace(*p))
       {
-         char * ws2p = ++p;         /* Point ws2p to the second ws char. */
-         while (isspace(*p))        /* Scan till we hit a non-ws char. */
+         char * ws2p = ++p;            /* Point ws2p to the second ws char. */
+         while (p < ep && isspace(*p)) /* Scan till we hit a non-ws char. */
             p++;
-         len -= p - ws2p;           /* Reduce the length by extra ws. */
-         memmove(ws2p, p, ep - p);  /* Overwrite the extra white space. */
+         len -= p - ws2p;              /* Reduce the length by extra ws. */
+         memmove(ws2p, p, ep - p);     /* Overwrite the extra white space. */
       }
       p++;
    }
@@ -821,6 +822,50 @@
 
 #ifdef SLP_COMPARE_TEST
 
+/* Test boundary conditions of SLPFoldWhiteSpace. */
+static int test_SLPFoldWhiteSpace(void)
+{
+   static char test_str0[] = "    ";
+   static char test_str1[] = "Blah";
+   static char test_str3[] = "Blah  blah";
+   static char test_str4[] = "Blah   blah";
+   static char test_str5[] = "Blah blah  blah";
+   static char test_str8[] = " Blah blah";
+   static char test_str9[] = "  Blah blah";
+   static char test_strC[] = "Blah blah      ";
+   static char test_strD[] = "Blah blah  xxxx";
+
+   static char * test_strs[] =
+   {
+      test_str0, test_str0, test_str0, test_str1, test_strC,
+      test_str3, test_str4, test_str5, test_strC, test_strC,
+      test_str8, test_str9, test_strC, test_strD,
+   };
+
+   static int test_lens[] =
+   {
+      0, 1, 2, 4, 9, 10, 11, 15, 10, 11, 10, 11, 11, 11,
+   };
+
+   static int test_fins[] =
+   {
+      0, 1, 1, 4, 9, 9, 9, 14, 10, 10, 10, 10, 10, 10,
+   };
+
+#define MAX_BUFSZ 32
+
+   int i;
+   for (i = 0; i < sizeof(test_strs) / sizeof(*test_strs); ++i)
+   {
+      char test_buf[MAX_BUFSZ];
+      memmove(test_buf, test_strs[i], test_lens[i]);
+      int len = SLPFoldWhiteSpace(test_lens[i], test_buf);
+      if (len != test_fins[i])
+         return -1;
+   }
+   return 0;
+}
+
 /* ---------------- Test main for the slp_compare.c module ----------------
  *
  * Compile with:
@@ -840,6 +885,9 @@
 
    int count;
 
+   if (test_SLPFoldWhiteSpace() != 0)
+      return -1;
+
    /* *** SLPContainsStringList ***
     */
    count = SLPContainsStringList(sizeof lst1 - 1, lst1, sizeof str1 - 1, str1);
